﻿package birdry.core
{
	import flash.display.DisplayObject;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.ui.Mouse;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.display.MovieClip;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	
	import flash.utils.Timer;
	import flash.events.TimerEvent;
	
	import birdry.utils.DisplayObjectUtil;
	import caurina.transitions.Tweener;
	
	import birdry.core.SaveDrawingEvent;
	
	/**
	* ...
	* @author 
	*/
	public class  SaveDrawing extends EventDispatcher	{
		
		var downFlag:Boolean;
		
		var pen:Object;
		var canvas:Object;
		
		public var lineThickness:uint = 2;
		public var lineColor:uint = 0x000000;
		public var lineAlpha:uint = 1;
		public var replayFlag:Boolean;
		
		var savePosition:Point;
		var saveArr:Array = new Array();
		var replayNum:uint;
		var timer:Timer;
		
		public var inkMax:uint = 2000;
		
		public function SaveDrawing( obj: DisplayObject, canvas: DisplayObject ): void	{
			this.pen = obj;
			this.canvas = canvas;
		}
		
		public function start(): void	{
			if (replayFlag)	return;
			addEvent();
			Mouse.hide();
			pen.visible = true;
		}
		
		public function stop(): void	{
			removeEvent();
			Mouse.show();
			pen.visible = false;
		}
		
		public function replay(): void	{
			replayFlag = true;
			stop();
			DisplayObjectUtil.removeDisplayObject(canvas, false);
			replayNum = 0;
			timer = new Timer(1, saveArr.length);
			timer.addEventListener(TimerEvent.TIMER, onTimer);
			timer.addEventListener(TimerEvent.TIMER_COMPLETE, onTimerComplete);
			timer.start();
		}
		
		private function onTimer( e: TimerEvent ): void	{
			lineDraw( saveArr[ replayNum ]  );
			replayNum++;
		}
		
		private function onTimerComplete( e: TimerEvent ): void	{
			replayFlag = false;
			start();
		}
		
		private function addEvent(): void	{
			canvas.stage.addEventListener(MouseEvent.MOUSE_MOVE, onMove);
			canvas.stage.addEventListener(MouseEvent.MOUSE_DOWN, onDown);
		}
		
		private function removeEvent(): void	{
			canvas.stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMove);
			canvas.stage.removeEventListener(MouseEvent.MOUSE_DOWN, onDown);
		}
		
		private function onDown( e: MouseEvent ): void	{
			savePosition = new Point(canvas.mouseX, canvas.mouseY);
			downFlag = true;
			canvas.stage.addEventListener(MouseEvent.MOUSE_UP, onUp);
		}
		
		private function onMove( e: MouseEvent ): void	{
			pen.x = canvas.mouseX;
			pen.y = canvas.mouseY;
			if (downFlag)	{
				drawing();
				inkFullClearing();
			}
		}
		
		private function onUp( e: MouseEvent ): void	{
			downFlag = false;
			canvas.stage.removeEventListener(MouseEvent.MOUSE_UP, onUp);
		}
		
		private function drawing(): void	{
			if (!downFlag)	return;
			
			var lineInfoObj:Object = new Object();
			lineInfoObj.thickness = lineThickness;
			lineInfoObj.color = lineColor;
			lineInfoObj.alpha = lineAlpha;
			lineInfoObj.moveTo = savePosition;
			lineInfoObj.lineTo = new Point(canvas.mouseX, canvas.mouseY);
			
			lineDraw( lineInfoObj );
			saveArr.push( lineInfoObj );
			
			savePosition = new Point(canvas.mouseX, canvas.mouseY);
			dispatchEvent(new SaveDrawingEvent(SaveDrawingEvent.DRAWING, saveArr.length / inkMax));
		}
		
		private function lineDraw( lineInfoObj:Object ): void	{
			var sprite:Shape = new Shape();
			sprite.graphics.lineStyle(lineInfoObj.thickness, lineInfoObj.color, lineInfoObj.alpha);
			sprite.graphics.moveTo(lineInfoObj.moveTo.x, lineInfoObj.moveTo.y);
			sprite.graphics.lineTo(lineInfoObj.lineTo.x, lineInfoObj.lineTo.y);
			canvas.addChild(sprite);
			lineInfoObj.obj = sprite;
		}
		
		private function inkFullClearing(): void	{
			if (saveArr.length > inkMax)	{
				Tweener.addTween(saveArr[0].obj, { alpha:0, time:0.5, onComplete:tweenComplete, transition:"linear", onCompleteParams:[saveArr[0].obj] } );
				saveArr.shift();
			}
		}
		
		private function tweenComplete( obj: Object ): void	{
			canvas.removeChild(obj);
		}
		
	}	// class
	
}	// package